package com.yenlien.traceyun.plant.service;

import com.yenlien.traceyun.business.dao.ClientOrderDetailDao;
import com.yenlien.traceyun.business.dao.RecallDao;
import com.yenlien.traceyun.business.dao.StorageManageDao;
import com.yenlien.traceyun.business.entity.ClientOrderDetailed;
import com.yenlien.traceyun.business.entity.Recall;
import com.yenlien.traceyun.business.entity.RecallChain;
import com.yenlien.traceyun.business.entity.StorageManage;
import com.yenlien.traceyun.business.interceptor.UserAuthUtil;
import com.yenlien.traceyun.business.service.RecallService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.util.*;
import java.util.stream.Collectors;

/**
 * @author: bigwangy@sina.com
 * @create: 2020-12-17
 * @description:
 **/

@Service
public class PlantRecallService {

    @Autowired
    private RecallService recallService;

    @Autowired
    private ClientOrderDetailDao clientOrderDetailDao;

    @Autowired
    private RecallDao recallDao;

    @Autowired
    private StorageManageDao storageManageDao;

    @Value("${traceyun.app.id}")
    private String appId;


    public List<RecallChain> getRecallChain(Recall recall) throws Exception {
        List<RecallChain> chains = recallService.getRecallChain(recall);
        List<RecallChain> result = new ArrayList<>();
        List<RecallChain> traceresult = new ArrayList<>();
        List<RecallChain> purchaseresult = new ArrayList<>();
        if (chains != null && chains.size() > 0) {
            for (RecallChain chain : chains) {
                //采购入库的线路
                if (chain.getBranch().equals("purchase") && chain.getTraceStep().equals("storageManage")) {
                    purchaseresult.add(chain);
                }
                //生产路线
                if (chain.getBranch().equals("trace") && chain.getTraceStep().equals("subpackage")) {
                    traceresult.add(chain);
                }
            }
        }
        if (traceresult.size() > 0) {
            Set<String> relateIds = traceresult.stream().map(p -> p.getRelateId()).collect(Collectors.toSet());
            if (relateIds.size() > 0) {
                List<StorageManage> manageList = storageManageDao.findByRelateIdIn(relateIds);
                Set<String> mIds = manageList.stream().map(p -> p.getId()).collect(Collectors.toSet());
                if (mIds.size() > 0) {
                    List<ClientOrderDetailed> detaileds = clientOrderDetailDao.findByRelateIdIn(mIds);
                    if (detaileds != null && detaileds.size() > 0) {
                        Map<String, String> map = new HashMap<>();
                        for (StorageManage m : manageList) {
                            Set<String> clientNames = new HashSet<>();
                            for (ClientOrderDetailed detailed : detaileds) {
                                if (m.getId().equals(detailed.getRelateId())) {
                                    clientNames.add(detailed.getClientName());
                                }
                            }
                            if (clientNames.size() > 0) {
                                String old = map.get(m.getRelateId());
                                if (StringUtils.isEmpty(old)) {
                                    old = "";
                                }
                                map.put(m.getRelateId(), old + listToString(clientNames));
                            }
                        }
                        for (RecallChain chain : traceresult) {
                            chain.setClientName(map.get(chain.getRelateId()));
                        }
                    }
                }
            }
            result.addAll(traceresult);
        }

        if (purchaseresult.size() > 0) {
            Set<String> relateIds = purchaseresult.stream().map(p -> p.getRelateId()).collect(Collectors.toSet());
            if (relateIds.size() > 0) {

                List<ClientOrderDetailed> detaileds = clientOrderDetailDao.findByRelateIdIn(relateIds);
                if (detaileds != null && detaileds.size() > 0) {
                    for (RecallChain chain : purchaseresult) {
                        Set<String> clientNames = new HashSet<>();
                        for (ClientOrderDetailed detailed : detaileds) {
                            if (chain.getRelateId().equals(detailed.getRelateId())) {
                                clientNames.add(detailed.getClientName());
                            }
                        }
                        if (clientNames.size() > 0) {
                            chain.setClientName(listToString(clientNames));
                        }
                    }
                }

            }
            result.addAll(purchaseresult);
        }


        return result;
    }

    @Transactional(rollbackFor = RuntimeException.class)
    public Recall save(Recall recall, List<RecallChain> chains) {
        recall.setAppId(appId);
        recall.setCompanyId(UserAuthUtil.getLoginUser().getCompanyId());
        recall.setUsername(UserAuthUtil.getLoginUser().getUsername());
        Set<String> batchs = (chains.stream().map(p -> p.getBatch()).collect(Collectors.toSet()));
        storageManageDao.updateRecallBySourceBatch(batchs);
        return recallService.save(recall, chains);
    }

    public String listToString(Set<String> arr) {
        StringBuffer stringBuffer = new StringBuffer();
        if (arr != null && arr.size() > 0) {
            for (String item : arr) {
                stringBuffer.append(",").append("'").append(item).append("'");
            }
            return stringBuffer.substring(1);
        } else {
            return null;
        }
    }
}
